Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add freestanding RTTI::to, RTTI::is, RTTI::isAny #4696

Merged
merged 4 commits into from
Jun 3, 2024
Merged

Conversation

vlstill
Copy link
Contributor

@vlstill vlstill commented May 31, 2024

This PR adds rtti_utils.h (split so that it can be included only when needed, ideally just to .cpp files). It contains type traits which help with use of RTTI and, more imporantly it adds three freestanding function-like objects (using similar principle as the C++20 ranges):

  • RTTI::to
  • RTTI::is
  • RTTI::isAny<Ts...>

The names should make it quite clear what these are... they are freestanding wrappers over ->to and ->is.

  • They don't fail if nullptr is passed into them, they just return nullptr/false.
  • They can be also used as function objects (passed to std algorithms, etc.).
  • isAny<Ts...> is variadic and accepts any (non-zero) number of type arguments and checks if the passed object is instance of at least one of them.

This makes some uses of the RTTI simpler, especially in cases where:

  • the object can be validly null;
  • a callable needs to be passed, this avoids having to create ad-hoc lambdas like [](const IR::Node *t) { return t->is<IR::Declaration>(); } in standard algorithms;
  • one wants to check if an object is one of multiple types;
  • the object's type is templated and therefore the call would have to be something like foo->template is<IR::Constant>() which is quite ugly in my opinion.

@vlstill vlstill marked this pull request as ready for review May 31, 2024 08:18
@vlstill vlstill requested review from asl and fruffy May 31, 2024 08:19
@vlstill vlstill self-assigned this May 31, 2024
@vlstill vlstill added the core Topics concerning the core segments of the compiler (frontend, midend, parser) label May 31, 2024
@fruffy
Copy link
Collaborator

fruffy commented May 31, 2024

I would merge this into castable or a separate castable_rtti.h class to make the purpose of the header clear. rtti_utils might be too broad.

@vlstill
Copy link
Contributor Author

vlstill commented May 31, 2024

I would merge this into castable or a separate castable_rtti.h class to make the purpose of the header clear. rtti_utils might be too broad.

I can rename the header. To me it is quite tightly bound rtti.h itself, but I did not want to introduce more templates into a header that is included basically everywhere. I don't think putting it into castable.h makes much sense for the same reason and also it works for anything RTTI::Base-derived.

Also is not just casts but traits too (and concepts in future). I don't have a better name right now thought, naming is hard :-(.

@asl
Copy link
Contributor

asl commented May 31, 2024

I think the name of the header is fine. There might be some other utils in the future (e.g. some kind of reflection or typeid name or whatever).

/// A trait that check T is custom-RTTI-enabled. Works just like standard property type traits.
/// One would normally use the _v variant.
template <typename T>
struct has_rtti : std::is_base_of<RTTI::Base, T> {};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are two pieces of RTTI in general:

  • One needs to be derived from RTTI:Base (plus all its bases must be derived from RTTI::Base)
  • One has appropriate methods implementation (e.g. via DECLARE_TYPEINFO-kind macro)

I think it's ok to check just for the base class here – TypeInfo will check for the whole set of constraints anyway should the RTTI methods are invoked.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I'd say being derived from RTTI::Base without the proper macros is definitely a bug, so firing a static_assert instead of the proper SFINAE-enabling failure in that case seems fine to me.

*/

/// @file
/// @brief Utilities that help with use of custom-RTTI-enabled classes.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe worth mentioning in docs/C++.md?

Copy link
Contributor

@asl asl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, plus few minor nits and notes

@fruffy
Copy link
Collaborator

fruffy commented May 31, 2024

I think the name of the header is fine. There might be some other utils in the future (e.g. some kind of reflection or typeid name or whatever).

Names like utils, common, helper etc can be ambiguous and it's easy to forget what is actually in them. Personally, I have started to refrain from using them to avoid creating kitchen-sink headers.

@asl
Copy link
Contributor

asl commented May 31, 2024

Personally, I have started to refrain from using them to avoid creating kitchen-sink headers.

Yes, that's common problem is that utils starts to contain everything and their dog. So we'd need to carefully review all changes that eventually would be added there.

@vlstill vlstill requested a review from asl June 3, 2024 06:53
@vlstill
Copy link
Contributor Author

vlstill commented Jun 3, 2024

Personally, I have started to refrain from using them to avoid creating kitchen-sink headers.

Yes, that's common problem is that utils starts to contain everything and their dog. So we'd need to carefully review all changes that eventually would be added there.

I agree these kinds of headers can accumulate a lot of unrelated stuff. But we can always split it if there is more. I presume some patterns would start to emerge. Currently there are two kinds of stuff in the header, traits and cast functions and the second depends on the first, so naming it more concretely is tricky.

@vlstill vlstill added this pull request to the merge queue Jun 3, 2024
Merged via the queue into main with commit b2778cf Jun 3, 2024
17 checks passed
@vlstill vlstill deleted the vstill/rtti-utils branch June 3, 2024 14:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
core Topics concerning the core segments of the compiler (frontend, midend, parser)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants